package com.ssyx.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ssyx.constant.GlobalConstant;
import com.ssyx.constant.RedisConstant;
import com.ssyx.mapper.SeckillSkuMapper;
import com.ssyx.model.activity.SeckillSku;
import com.ssyx.model.product.SkuInfo;
import com.ssyx.product.ProductFeignClient;
import com.ssyx.service.RabbitMQService;
import com.ssyx.service.SeckillSkuService;
import com.ssyx.vo.activity.SeckillSkuQueryVo;
import com.ssyx.vo.activity.SeckillSkuVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: ssyx-parent
 * @className: SeckillSkuServiceImpl
 * @description: 类
 * @data: 2024/3/15 21:14
 * @author: ihu
 * @version: 1.0
 **/

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class SeckillSkuServiceImpl extends ServiceImpl<SeckillSkuMapper, SeckillSku> implements SeckillSkuService {
	
	@Resource
	private SeckillSkuMapper seckillSkuMapper;
	@Resource
	private ProductFeignClient productFeignClient;
	@Resource
	private RedisTemplate redisTemplate;
	@Resource
	private RabbitMQService rabbitMQService;
	
	@Override
	public IPage<SeckillSku> selectPage(Page<SeckillSku> pageParam, SeckillSkuQueryVo seckillSkuQueryVo) {
		IPage<SeckillSku> seckillSkuIPage = baseMapper.selectPage(pageParam,
				Wrappers.<SeckillSku>lambdaQuery().like(SeckillSku::getSkuId, seckillSkuQueryVo.getSeckillId()).or().eq(SeckillSku::getSeckillTimeId, seckillSkuQueryVo.getSeckillTimeId()));
		if (CollectionUtils.isEmpty(seckillSkuIPage.getRecords())) return seckillSkuIPage;
		// 查询sku信息
		List<Long> skuIdList =
				seckillSkuIPage.getRecords().stream().map(SeckillSku::getSkuId).collect(Collectors.toList());
		List<SkuInfo> skuInfoList = productFeignClient.findSkuInfoList(skuIdList);
		Map<Long, SkuInfo> skuIdToSkuInfoMap = skuInfoList.stream().collect(Collectors.toMap(SkuInfo::getId, e -> e));
		seckillSkuIPage.getRecords().forEach(e -> e.setSkuInfo(skuIdToSkuInfoMap.get(e.getSkuId())));
		return seckillSkuIPage;
	}

//	@Override
//	public void saveSeckillSku(List<SeckillSku> seckillSkuList) {
//		saveBatch(seckillSkuList);
//		//更新sku为秒杀商品
////		List<Long> skuIdList = seckillSkuList.stream().map(SeckillSku::getSkuId).collect(Collectors.toList());
	// todo
////		productFeignClient.updateSkuType(skuIdList, SkuType.SECKILL);
//	}
	
	@Override
	public List<SeckillSkuVo> findSeckillSkuListFromCache(String timeName) {
		List<SeckillSkuVo> seckillSkuVoList = redisTemplate.boundHashOps(RedisConstant.SECKILL_SKU_MAP).values();
		if (seckillSkuVoList != null && seckillSkuVoList.size() > GlobalConstant.INTEGER_ONE) {
			seckillSkuVoList.add(seckillSkuVoList.get(GlobalConstant.INTEGER_ZERO));
		}
		return seckillSkuVoList;
		//return  seckillSkuVoList.stream().filter(seckillSkuVo -> timeName.equals( seckillSkuVo.getTimeName())).collect(
		// Collectors.toList() );
	}

//	@Override
//	public SeckillSkuVo getSeckillSkuVo(Long skuId) {
//		SeckillSkuVo seckillSkuVo =
//				(SeckillSkuVo) redisTemplate.boundHashOps(RedisConstant.SECKILL_SKU_MAP).get(skuId.toString());
//		if (seckillSkuVo == null) {
//			String date = new DateTime().toString("yyyy-MM-dd");
//			saveSeckillSkuListToCache(date);
//		}
//		// 场次状态 1：已开抢 2：抢购中 3：即将开抢
//		Date currentDate = DateUtil.parseTime(new DateTime().toString("HH:mm:ss"));
//		//即将开抢
//		if (seckillSkuVo != null && DateUtil.dateCompare(seckillSkuVo.getStartTime(), currentDate)) {
//			seckillSkuVo.setTimeStaus(GlobalConstant.INTEGER_ONE);
//		}
//		return seckillSkuVo;
//	}

//	@Transactional
//	@Override
//	public Boolean checkAndMinusStock(List<SkuStockLockVo> skuStockLockVoList, String orderToken) {
//		if (CollectionUtils.isEmpty(skuStockLockVoList)) {
//			throw new SsyxException(ResultCodeEnum.DATA_ERROR);
//		}
//		// 遍历所有商品，验库存并锁库存，要具备原子性
//		skuStockLockVoList.forEach(this::checkLock);
//		// 只要有一个商品锁定失败，所有锁定成功的商品要解锁库存
//		if (skuStockLockVoList.stream().anyMatch(skuStockLockVo -> !skuStockLockVo.getIsLock())) {
//			// 获取所有锁定成功的商品，遍历解锁库存
//			skuStockLockVoList.stream().filter(SkuStockLockVo::getIsLock).forEach(skuStockLockVo -> {
//				seckillSkuMapper.rollBackStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum());
//			});
//			// 响应锁定状态
//			return false;
//		}
//		// 如果所有商品都锁定成功的情况下，需要缓存锁定信息到redis。以方便将来解锁库存 或者 减库存
//		// 以orderToken作为key，以lockVos锁定信息作为value
//		redisTemplate.opsForValue().set(RedisConstant.SROCK_INFO + orderToken, skuStockLockVoList);
//
//		// 锁定库存成功之后，定时解锁库存。
//		rabbitMQService.sendMessage("ORDER_EXCHANGE", "stock.ttl", orderToken);
//		return true;
//	}

//	@Transactional
//	@Override
//	public void rollBackStock(String orderNo) {
//		// 获取锁定库存的缓存信息
//		List<SkuStockLockVo> skuStockLockVoList =
//				(List<SkuStockLockVo>) redisTemplate.opsForValue().get(RedisConstant.SROCK_INFO + orderNo);
//		if (CollectionUtils.isEmpty(skuStockLockVoList)) {
//			return;
//		}
//		// 回滚库存
//		skuStockLockVoList.forEach(skuStockLockVo -> {
//			SeckillSkuVo seckillSkuVo = this.getSeckillSkuVo(skuStockLockVo.getSkuId());
//			seckillSkuMapper.rollBackStock(seckillSkuVo.getSeckillSkuId(), skuStockLockVo.getSkuNum());
//		});
//
//		// 回滚库存之后，删除锁定库存的缓存。以防止重复解锁库存
//		redisTemplate.delete(RedisConstant.SROCK_INFO + orderNo);
//	}
	
	private void saveSeckillSkuListToCache(String date) {
		List<SeckillSkuVo> seckillSkuVoList = seckillSkuMapper.findSeckillSkuListByDate(date);
		if (CollectionUtils.isEmpty(seckillSkuVoList)) return;
		
		for (SeckillSkuVo seckillSkuVo : seckillSkuVoList) {
			//将秒杀sku信息放入缓存
			redisTemplate.boundHashOps(RedisConstant.SECKILL_SKU_MAP).put(seckillSkuVo.getSkuId().toString(), seckillSkuVo);
			//将库存数保存到redis队列，防止超卖
			Integer seckillStock = seckillSkuVo.getSeckillStock();
			Long[] skuIdArray = new Long[seckillStock];
			Arrays.fill(skuIdArray, seckillSkuVo.getSkuId());
			redisTemplate.boundListOps(RedisConstant.SECKILL_SKU_LIST + seckillSkuVo.getSkuId()).leftPushAll(skuIdArray);
			//设置过期时间
			//redisTemplate.expire(RedisConst.SECKILL_SKU_MAP, DateUtil.getCurrentExpireTimes(), TimeUnit.SECONDS);
		}
	}

//	@GmallLock
//	private void checkLock(SkuStockLockVo skuStockLockVo) {
//		SeckillSkuVo seckillSkuVo = this.getSeckillSkuVo(skuStockLockVo.getSkuId());
//		if (null == seckillSkuVo) return;
//
//		Integer result = seckillSkuMapper.minusStock(seckillSkuVo.getSeckillSkuId(), skuStockLockVo.getSkuNum());
//		if (result.equals(GlobalConstant.INTEGER_ONE)) {
//			skuStockLockVo.setIsLock(true);
//		}
//	}
	
	@Override
	public boolean removeById(Serializable id) {
		SeckillSku seckillSku = getById(id);
		seckillSkuMapper.deleteById(id);
		//更新sku为秒杀商品
		List<Long> skuIdList = new ArrayList<>();
		skuIdList.add(seckillSku.getSkuId());
		// todo
//		productFeignClient.updateSkuType(skuIdList, SkuType.COMMON);
		return false;
	}
}
